package com.suemi.missile.common.mql.maker;

import com.suemi.missile.common.mql.domain.Condition;
import com.suemi.missile.common.mql.domain.Where;
import com.suemi.missile.common.mql.exception.MqlParseException;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;

public class QueryMaker extends Maker {
  public static BoolQueryBuilder explan(Where where) throws MqlParseException {
    return explan(where, true);
  }

  public static BoolQueryBuilder explan(Where where, boolean isQuery) throws MqlParseException {
    BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
    while (where.getWheres().size() == 1) {
      where = where.getWheres().getFirst();
    }
    new QueryMaker().explanWhere(boolQuery, where);
    if (isQuery) {
      return boolQuery;
    }
    return QueryBuilders.boolQuery().filter(boolQuery);
  }

  private QueryMaker() {
    super(true);
  }

  private void explanWhere(BoolQueryBuilder boolQuery, Where where) throws MqlParseException {
    if (where instanceof Condition) {
      addSubQuery(boolQuery, where, (QueryBuilder) make((Condition) where));
    } else {
      BoolQueryBuilder subQuery = QueryBuilders.boolQuery();
      if(where.getBoost()!=null) subQuery.boost(where.getBoost());

      addSubQuery(boolQuery, where, subQuery);
      for (Where subWhere : where.getWheres()) {
        explanWhere(subQuery, subWhere);
      }
    }
  }

  private void addSubQuery(BoolQueryBuilder boolQuery, Where where, QueryBuilder subQuery) {
    if(where.getBoost()!=null) subQuery.boost(where.getBoost());
    if (where.getConn() == Where.CONN.AND) {
      boolQuery.must(subQuery);
    } else {
      boolQuery.should(subQuery);
    }
  }
}
